package com.corner.utils.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

import com.corner.presenter.IForgetPasswordPresenter;
import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import uk.co.senab.photoview.PhotoViewAttacher;

/**
 * 可缩放的ImageView
 * Created by Administrator on 2015/5/6.
 */
public class CustomImageView extends ImageView {
    public static final int DRAG = 1;
    public static final int ZOOM = 2;
    public static final int NONE = 3;
    private static final float K = 1.5f;
    private Bitmap bitmap;
//    private PointF startPoint;
//    private PointF newPosition;
//    private PointF downPosition;
//    private PointF midPoint;
//    private int mode;
    private Matrix imgMatrix;
    private Matrix savedMatrix;
    private Matrix startMatrix;
    private Matrix minMatrix;
//    private Matrix maxMatrix;
//    private double oldDistance;
//    private double newDistance;
    private float left;
    private float top;
    private int width;
    private int height;
    private boolean hasInit;
    private int viewHeight;
    private int viewWidth;
//    private boolean result;
    private PhotoViewAttacher attacher;
    private DataSource<CloseableReference<CloseableImage>> dataSource;


    public CustomImageView(Context context) {
        super(context);
        init();
    }

    public CustomImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void onDestroy() {
        if (bitmap!=null) {
            super.setImageBitmap(null);
            this.bitmap.recycle();
            this.bitmap = null;
        }
    }

    private void init() {
//        startPoint = new PointF();
//        newPosition = new PointF();
//        downPosition = new PointF();
//        midPoint = new PointF();
        savedMatrix = new Matrix();
        imgMatrix = new Matrix();
        startMatrix = new Matrix();
        minMatrix = new Matrix();
//        maxMatrix = new Matrix();
    }

    public void setAttacher(PhotoViewAttacher attacher) {
        this.attacher = attacher;
    }

    /**
     * 设置uri
     *
     * @param uri
     */
    public void setImageUri(Uri uri, final OnGetBitmapCallback callback) {
        ImageRequest imageRequest = ImageRequestBuilder
                .newBuilderWithSource(uri)
                .setProgressiveRenderingEnabled(true)
                .build();

        ImagePipeline imagePipeline = Fresco.getImagePipeline();
        dataSource = imagePipeline.fetchDecodedImage(imageRequest, getContext());
        dataSource.subscribe(new BaseBitmapDataSubscriber() {

                                 @Override
                                 public void onNewResultImpl(@Nullable Bitmap bitmap) {
                                     if (bitmap != null) {
                                         CustomImageView.this.bitmap = Bitmap.createBitmap(bitmap);
                                         dataSource.close();
                                         CustomImageView.this.post(new Runnable() {
                                             @Override
                                             public void run() {
                                                 if (callback != null) {
                                                     callback.onGetBitmap();
                                                 }
                                                 invalidate();
                                             }
                                         });
                                     }
                                 }

                                 @Override
                                 public void onFailureImpl(DataSource dataSource) {
                                 }
                             },
                CallerThreadExecutor.getInstance());

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 初始化bitmap，对bitmap进行缩放，获取到能居中放置的bitmap
     */
    private void initBitmap() {
        if (bitmap == null)
            return;
        setScaleType(ScaleType.MATRIX);
        width = bitmap.getWidth();
        height = bitmap.getHeight();
        // 获取View的宽高
        viewHeight = getMeasuredHeight();
        viewWidth = getMeasuredWidth();
        if (viewHeight == 0) {
            return;
        }

        // 计算图片最小时缩放的比例
        float scaleX = ((float) width) / viewWidth;
        float scaleY = ((float) height) / viewHeight;
        float minScale;
        // 计算bitmap放置在View中的位置
        if (scaleX < scaleY) {
            left = (viewWidth - width / scaleY) / 2.0f;
            top = 0;
            minScale = scaleY;
        } else {
            left = 0;
            top = (viewHeight - height / scaleX) / 2.0f;
            minScale = scaleX;
        }
        minMatrix.postScale(1 / minScale, 1 / minScale);
        minMatrix.postTranslate(left, top);

        float scale = ((float) width) / viewWidth;
        left = 0;
        top = (viewHeight - height / scale) / 2;
        imgMatrix.postScale(1 / scale, 1 / scale);
        imgMatrix.postTranslate(left, top);
        setImageMatrix(imgMatrix);
        savedMatrix.set(imgMatrix);
        startMatrix.set(imgMatrix);
        hasInit = true;

        setImageBitmap(bitmap);
        attacher.update();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (!hasInit) {
            initBitmap();
        }
        super.onDraw(canvas);
    }

//    private long lastTime;
//    private PointF lastPoint;

    public  interface OnGetBitmapCallback {
        void onGetBitmap();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (bitmap == null) {
            return true;
        }
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
//                startPoint.set(event.getX(), event.getY());
//                mode = DRAG;
//                result = false;
//                downPosition.set(startPoint);

//                if (lastPoint!=null){
//                    if (System.currentTimeMillis()-lastTime<200&&
//                            Math.sqrt(Math.pow(lastPoint.x - downPosition.x, 2) + Math.pow(lastPoint.y - downPosition.y, 2)) < 10f)
//                    {
//                        if (isScaled()){
//                            showSmall();
//                        }else{
//                            float[] startValues = new float[9];
//                            startMatrix.getValues(startValues);
//                            maxMatrix.reset();
//                            maxMatrix.postScale(startValues[0] * getMaxScale(), startValues[0] * getMaxScale());
//                            maxMatrix.postTranslate(viewWidth / 2-(downPosition.x-startValues[2]) * getMaxScale(),
//                                    viewHeight/2- (downPosition.y- startValues[5])* getMaxScale());
//                            setImageMatrix(maxMatrix);
//                            savedMatrix.set(maxMatrix);
//                        }
//                        result = true;
//                    }
//                }
//                if (result){
//                    lastPoint = null;
//                }else {
//                    lastTime = System.currentTimeMillis();
//                    lastPoint = downPosition;
//                }
//                result = false;
//                break;
//            case MotionEvent.ACTION_UP:
////                mode = NONE;
//                break;
//            case MotionEvent.ACTION_MOVE:
//                switch (mode) {
//                    case DRAG:
//                        newPosition.set(event.getX(), event.getY());
//                        result = Math.sqrt(Math.pow(newPosition.x - downPosition.x, 2) + Math.pow(newPosition.y - downPosition.y, 2)) > 10f;
//                        imgMatrix.set(savedMatrix);
//                        imgMatrix.postTranslate(K * (newPosition.x - startPoint.x), K * (newPosition.y - startPoint.y));
//                        ruleImgMatrix();
//                        setImageMatrix(imgMatrix);
//                        savedMatrix.set(imgMatrix);
//                        startPoint.set(newPosition);
//                        break;
//                    case ZOOM:
//                        newDistance = Math.sqrt(Math.pow(event.getX(0) - event.getX(1), 2) + Math.pow(event.getY(0) - event.getY(1), 2));
//                        if (newDistance > 10f) {
//                            result = true;
//                            float scale = (float) (newDistance / oldDistance);
//                            imgMatrix.set(savedMatrix);
//                            imgMatrix.postScale(scale, scale, midPoint.x, midPoint.y);
//                            ruleImgMatrix();
//                            setImageMatrix(imgMatrix);
//                            savedMatrix.set(imgMatrix);
//                            oldDistance = newDistance;
//                        } else {
//                            result = false;
//                        }
//                        break;
//                }
//                break;
//            case MotionEvent.ACTION_POINTER_DOWN:
//                oldDistance = Math.sqrt(Math.pow(event.getX(0) - event.getX(1), 2) + Math.pow(event.getY(0) - event.getY(1), 2));
//                if (oldDistance > 10f) {
//                    mode = ZOOM;
//                    midPoint.set((event.getX(0) + event.getX(1)) / 2, (event.getY(0) + event.getY(1)) / 2);
//                }
//                break;
//            case MotionEvent.ACTION_POINTER_UP:
//                mode = NONE;
//                break;
        }
//        if (result && event.getAction() == MotionEvent.ACTION_UP) {
//            return true;
//        }
        return super.onTouchEvent(event);
    }
//
//
//    private void ruleImgMatrix() {
//        float[] values = new float[9];
//        float[] minValues = new float[9];
//        float[] startValues = new float[9];
//        startMatrix.getValues(startValues);
//        minMatrix.getValues(minValues);
//        imgMatrix.getValues(values);
//        if (values[0] <= minValues[0]) {
//            imgMatrix.setValues(minValues);
//            return;
//        }
//        if (values[0] > getMaxScale() * startValues[0]) {
//            values[0] = values[4] = getMaxScale() * startValues[0];
//            float[] savedValues = new float[9];
//            savedMatrix.getValues(savedValues);
//            values[2] = savedValues[2];
//            values[5] = savedValues[5];
//        }
//        if (viewWidth <= width * values[0] && values[2] < viewWidth - width * values[0]) {
//            values[2] = viewWidth - width * values[0];
//        } else if (values[2] > 0 && viewWidth <= width * values[0]) {
//            values[2] = 0;
//        } else if (viewWidth > width * values[0]) {
//            values[2] = (viewWidth - width * values[0]) / 2;
//        }
//
//        if (viewHeight < height * values[0] && values[5] < viewHeight - height * values[0]) {
//            values[5] = viewHeight - height * values[0];
//        } else if (values[5] > 0 && viewHeight <= height * values[0]) {
//            values[5] = 0;
//        } else if (viewHeight > height * values[0]) {
//            values[5] = (viewHeight - height * values[0]) / 2;
//        }
//        imgMatrix.setValues(values);
//    }
//
//    protected int getMaxScale() {
//        return 3;
//    }
//
//    public boolean isScaled() {
//        return !(imgMatrix.equals(startMatrix) || imgMatrix.equals(minMatrix));
//    }

//    public void showSmall() {
//        imgMatrix.set(minMatrix);
//        savedMatrix.set(minMatrix);
//    }
}
